import datetime
import os
import shelve
import sys
import time

from PyQt5 import QtWidgets
from PyQt5.QtCore import pyqtSignal, QThread
from PyQt5.QtWidgets import QMainWindow

from core import down, m3u8
from gui.Mdgui import Ui_MainWindow


class mdwindows(QMainWindow,Ui_MainWindow):
    def __init__(self):
        super(mdwindows,self).__init__()
        self.ui = Uiupdate()
        self.work = WorkThread()
        self.setupUi(self)
        self.downstatu = False # False 表示当前无下载任务
        self.clear()
        self.build()
        self.downButton.clicked.connect(self.excute)
        self.work.trigger_text.connect(self.display_text)
        self.work.trigger_downstatu.connect(self.set_downstatu)
        self.work.trigger_uistatu.connect(self.guiupdate)
        self.work.trigger_progressbar.connect(self.display_progressbar)
    def excute(self):
        if self.check():
            if self.downstatu==False:
                self.work.start()
            else:
                self.textBrowser.append("已有任务正在下载......")


    def check(self):
        path = self.pathEdit.text()
        url = self.urlEdit.text()
        name = self.nameEdit.text()
        if (path!="")&(url!="")&(name!=""):
            with shelve.open("Mdshelve","c") as f:
                inp = {"url":url,"path":path,"name":name}
                f["input"] = inp
            try:
                if not os.path.exists(path):
                    os.mkdir(path)
                    print("路径创建成功")
            except Exception as e:
                self.textBrowser.setText(str(e))
                print(repr(e))
            return True
        else:
            self.textBrowser.setText("请输入完整信息")
            return False

    def clear(self):
        workcat = os.getcwd()
        try:
            os.remove(workcat + "\\Mdshelve.dat" )
            os.remove(workcat + "\\Mdshelve.bak")
            os.remove(workcat + "\\Mdshelve.dir")
        except Exception as e:
            print(repr(e))

    def build(self):
        with shelve.open("Mdshelve","c")as f:
            f["input"] = {"url":"","path":"","name":"" }
            f["ts_lists"] = []
            f["th_pathlist"] = []
            f["total"] = 0
            f["threadnum"] = 0
            f["retry_num"] = 10
            f["downstatu"] = False
            f["uistatu"] = False

    def display_text(self,string):
        self.textBrowser.setText(string)
    def display_progressbar(self,num):
        if num<=99:
            self.progressBar.setValue(num)
        else:
            self.progressBar.setValue(99)
    def set_downstatu(self,b):
        self.downstatu = b
    def guiupdate(self,b):
        try:
            if b:
                self.ui.trigger_progressbar.connect(self.display_progressbar)
                self.ui.start()
            else:
                self.ui.quit()
        except Exception as e:
            print(repr(e))


class WorkThread(QThread):
    trigger_text = pyqtSignal(str)
    trigger_downstatu = pyqtSignal(bool)
    trigger_uistatu = pyqtSignal(bool)
    trigger_progressbar = pyqtSignal(int)
    def __init__(self):
        super(WorkThread,self).__init__()

    def run(self):
        url = ""
        path = ""
        name = ""
        with shelve.open("Mdshelve","c") as f:
            inp = f.get("input")
            url = inp["url"]
            path = inp["path"]
            name = inp["name"]
        self.trigger_text.emit("开始解析")
        try:
            m = m3u8.m3u8(url)
            key,ts_lists = m.get_key_tsurl()
            threadnum = self.autothreadnum(ts_lists)
            th_pathlist = []
            for i in range(threadnum):
                t = path + "\\th-" + str(i)
                th_pathlist.append(t)
            with shelve.open("Mdshelve","c") as f:
                f["key"] = key
                f["ts_lists"] = ts_lists
                f["total"] = len(ts_lists)
                f["th_pathlist"] = th_pathlist
                f["uistatu"] = True
            self.trigger_text.emit("解析成功,开始下载")
        except Exception as e:
            self.trigger_text.emit("解析错误\n" + str(e))
            print(repr(e))
        self.trigger_downstatu.emit(True)
        self.trigger_uistatu.emit(True)
        try:
            start = datetime.datetime.now().replace(microsecond=0)
            do = down.down(ts_lists, key, path, name, 10, 0)
            re = do.download()
            end = datetime.datetime.now().replace(microsecond=0)
            if len(re)==0:
                self.trigger_text.emit("下载完成\n" + "用时：" + str(end - start)+"\n开始合并")
            else:
                self.trigger_text.emit("部分ts下载失败\n" + "用时：" + str(end - start)+ "\n开始合并")
            self.trigger_uistatu.emit(False)
            self.trigger_progressbar.emit(0)
        except Exception as e:
            self.trigger_text.emit("下载失败\n" + str(e))
            print(repr(e))
        try:
            do.combine()
            over = datetime.datetime.now().replace(microsecond=0)
            self.trigger_text.emit("合并完成\n" + "总用时：" + str(over - start) )
            self.trigger_downstatu.emit(False)
        except Exception as e:
            self.trigger_text.emit(str(e))


    def autothreadnum(self,tsurl_list) -> int:
        """
        自动生成线程数
        :param tsurl_lists:ts下载地址列表 
        :param path:下载地址
        :return: 线程数
        """
        n = len(tsurl_list)
        n = (int)(n / 20) + 1
        if n <= 32:
            return n
        else:
            return 32


class Uiupdate(QThread):
    trigger_progressbar = pyqtSignal(int)
    def __init__(self):
        super(Uiupdate,self).__init__()

    def run(self):
        with shelve.open("Mdshelve","c") as f:
            th_pathlist = f.get("th_pathlist")
            print(th_pathlist)
            total = f.get("total")
            print(total)
        while(1):
            sum = 0
            try:
                time.sleep(2)
                for p in th_pathlist:
                    for root,dirs,file in os.walk(p):
                        sum = sum + len(file)
                self.trigger_progressbar.emit(int(sum/total*100))
                time.sleep(2)
            except Exception as e:
                print("UI:"+repr(e))


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    md = mdwindows()
    md.show()
    sys.exit(app.exec_())




